package com.example.myapplication;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class TaskManager {

    //执行大量耗时较少的任务，最常用来替代 new Thread
    private ExecutorService cachedThreadPool = Executors.newCachedThreadPool();

    private TaskManager() {}

    /**
     * TaskManager被加载时，TaskManagerHolder不会被初始化。这是一种延迟加载的策略，避免了获取单例使用同步关键字
     */
    private static class TaskManageHolder {
        /* 创建类时构造实例，天生对多线程友好*/
        private static TaskManager instance = new TaskManager();

    }

    public static TaskManager getInstance() {
        return TaskManageHolder.instance;
    }

    public void executeTask(Runnable runnable) {
        cachedThreadPool.execute(runnable);
    }

    //==============================================================================================
    //延时可用
    private ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(4);

    /**
     * 延时多少毫秒后执行
     *
     * @param delaySeconds
     * @param runnable
     */
    public void executeTaskDelay(int delaySeconds, Runnable runnable) {
        scheduledThreadPool.schedule(runnable, delaySeconds, TimeUnit.MILLISECONDS);
    }

    /**
     * 延迟多少毫秒后，每隔cycleTime毫秒执行一次
     *
     * @param delaySeconds
     * @param cycleTime
     * @param runnable
     */
    public void executeTaskCycle(int delaySeconds, int cycleTime, Runnable runnable) {
        scheduledThreadPool.scheduleAtFixedRate(runnable, delaySeconds, cycleTime, TimeUnit.MILLISECONDS);
    }

    //==============================================================================================
    //顺序执行，不需要处理线程同步的问题
    private ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();

    /**
     * 执行同步任务
     *
     * @param runnable
     */
    public void executeTaskOrder(Runnable runnable) {
        singleThreadExecutor.execute(runnable);
    }

    //==============================================================================================
    private ExecutorService fixedThreadPool = Executors.newFixedThreadPool(4);

    /**
     * 最快速相应外界请求，核心线程，不会被回收
     *
     * @param runnable
     */
    public void executeTaskZoom(Runnable runnable) {
        fixedThreadPool.execute(runnable);
    }
}
